stylecontext: Keep track of the CSS ID
authorBenjamin Otte <otte@redhat.com>
Mon, 19 Jan 2015 23:33:34 +0000 (00:33 +0100)
committerBenjamin Otte <otte@redhat.com>
Tue, 20 Jan 2015 00:07:13 +0000 (01:07 +0100)
This is necessary since we do the new caching and need to distinguish
between styles with different IDs.

Fixes various test cases.

gtk/gtkcssnodedeclaration.c
gtk/gtkcssnodedeclarationprivate.h
gtk/gtkstylecontext.c
gtk/gtkstylecontextprivate.h
gtk/gtkwidget.c

index e5c718708ad9f0490b0a3aee7bbd3b2f94d7d3b2..989ad94fd463bfdb47b7e292ed79ec12b9676da7 100644 (file)
@@ -33,6 +33,7 @@ struct _GtkCssNodeDeclaration {
   guint refcount;
   GtkJunctionSides junction_sides;
   GType type;
+  const /* interened */ char *id;
   GtkStateFlags state;
   guint n_classes;
   guint n_regions;
@@ -180,6 +181,27 @@ gtk_css_node_declaration_get_type (const GtkCssNodeDeclaration *decl)
   return decl->type;
 }
 
+gboolean
+gtk_css_node_declaration_set_id (GtkCssNodeDeclaration **decl,
+                                 const char             *id)
+{
+  id = g_intern_string (id);
+
+  if ((*decl)->id == id)
+    return FALSE;
+
+  gtk_css_node_declaration_make_writable (decl);
+  (*decl)->id = id;
+
+  return TRUE;
+}
+
+const char *
+gtk_css_node_declaration_get_id (const GtkCssNodeDeclaration *decl)
+{
+  return decl->id;
+}
+
 gboolean
 gtk_css_node_declaration_set_state (GtkCssNodeDeclaration **decl,
                                     GtkStateFlags           state)
@@ -447,6 +469,8 @@ gtk_css_node_declaration_hash (gconstpointer elem)
   guint hash, i;
   
   hash = (guint) decl->type;
+  hash <<= 5;
+  hash ^= GPOINTER_TO_UINT (decl->id);
 
   classes = get_classes (decl);
   for (i = 0; i < decl->n_classes; i++)
@@ -488,6 +512,9 @@ gtk_css_node_declaration_equal (gconstpointer elem1,
   if (decl1->state != decl2->state)
     return FALSE;
 
+  if (decl1->id != decl2->id)
+    return FALSE;
+
   if (decl1->n_classes != decl2->n_classes)
     return FALSE;
 
index 56323ac5063a7f7763282a992901bce675254b75..f2679748c8aa71c18af81b071f155e16adc44792 100644 (file)
@@ -36,6 +36,9 @@ GtkJunctionSides        gtk_css_node_declaration_get_junction_sides     (const G
 gboolean                gtk_css_node_declaration_set_type               (GtkCssNodeDeclaration        **decl,
                                                                          GType                          type);
 GType                   gtk_css_node_declaration_get_type               (const GtkCssNodeDeclaration   *decl);
+gboolean                gtk_css_node_declaration_set_id                 (GtkCssNodeDeclaration        **decl,
+                                                                         const char                    *id);
+const char *            gtk_css_node_declaration_get_id                 (const GtkCssNodeDeclaration   *decl);
 gboolean                gtk_css_node_declaration_set_state              (GtkCssNodeDeclaration        **decl,
                                                                          GtkStateFlags                  flags);
 GtkStateFlags           gtk_css_node_declaration_get_state              (const GtkCssNodeDeclaration   *decl);
index f107a73c50ac92ec2b06cbcdc4b37119a151492c..dc185bfb814bbbae9fdf856ae40207b0884549a6 100644 (file)
@@ -1338,6 +1338,42 @@ gtk_style_context_get (GtkStyleContext *context,
   va_end (args);
 }
 
+/*
+ * gtk_style_context_set_id:
+ * @context: a #GtkStyleContext
+ * @id: (allow-none): the id to use or %NULL for none.
+ *
+ * Sets the CSS ID to be used when rendering with any
+ * of the gtk_render_*() functions.
+ **/
+void
+gtk_style_context_set_id (GtkStyleContext *context,
+                          const char      *id)
+{
+  g_return_if_fail (GTK_IS_STYLE_CONTEXT (context));
+
+  if (!gtk_css_node_declaration_set_id (&context->priv->cssnode->decl, id))
+    return;
+
+  gtk_style_context_queue_invalidate_internal (context, GTK_CSS_CHANGE_ID);
+}
+
+/*
+ * gtk_style_context_get_id:
+ * @context: a #GtkStyleContext
+ *
+ * Returns the CSS ID used when rendering.
+ *
+ * Returns: the ID or %NULL if no ID is set.
+ **/
+const char *
+gtk_style_context_get_id (GtkStyleContext *context)
+{
+  g_return_val_if_fail (GTK_IS_STYLE_CONTEXT (context), NULL);
+
+  return gtk_css_node_declaration_get_id (context->priv->cssnode->decl);
+}
+
 /**
  * gtk_style_context_set_state:
  * @context: a #GtkStyleContext
index 4b9486693bbedf04f8cd4effcee55c2d49f3e1e5..45f8ad27c35b7422afd816d7497ae9bdbd86130f 100644 (file)
@@ -29,6 +29,10 @@ G_BEGIN_DECLS
 
 void            _gtk_style_context_set_widget                (GtkStyleContext *context,
                                                               GtkWidget       *widget);
+void            gtk_style_context_set_id                     (GtkStyleContext *context,
+                                                              const char      *id);
+const char *    gtk_style_context_get_id                     (GtkStyleContext *context);
+
 const GtkBitmask *
                 _gtk_style_context_get_changes               (GtkStyleContext *context);
 
index 65fd0959ffcccd3e4196a3e18db3bfd9a5e7fc0b..66ad052db563143cdea8d1642c5dbbbe6bfd8e38 100644 (file)
@@ -8712,7 +8712,8 @@ gtk_widget_set_name (GtkWidget     *widget,
   g_free (priv->name);
   priv->name = new_name;
 
-  _gtk_widget_invalidate_style_context (widget, GTK_CSS_CHANGE_NAME);
+  if (priv->context)
+    gtk_style_context_set_id (priv->context, priv->name);
 
   g_object_notify (G_OBJECT (widget), "name");
 }
@@ -16370,6 +16371,7 @@ gtk_widget_get_style_context (GtkWidget *widget)
 
       priv->context = gtk_style_context_new ();
 
+      gtk_style_context_set_id (priv->context, priv->name);
       gtk_style_context_set_state (priv->context, priv->state_flags);
       gtk_style_context_set_scale (priv->context, gtk_widget_get_scale_factor (widget));